__author__ = "Николай Витальевич Никоноров (Bitnik212)"
__date__ = "26.01.2024 23:49"

from functools import lru_cache
from pathlib import Path


class TestPropertiesService:

    def __init__(self, file_name: str = "tests.env"):
        self.env_file: Path | None = Path(self.__check_file(file_name))

    @staticmethod
    @lru_cache
    def __check_file(file_name: str) -> str:
        for path in list(Path().absolute().parents):
            if (path / file_name).exists():
                return str(path / file_name)

    def load(self) -> dict:
        result = {}
        with open(self.env_file, 'r') as file:
            content = file.read()
            for field in content.split("\n"):
                if field != '':
                    field_dict = self.string_to_dict(*field.split("="))
                    result = self.merge_dicts(from_dict=result, to_dict=field_dict)
        return result

    @classmethod
    def string_to_dict(cls, key: str, value, result=None) -> dict:
        result = result or {}
        keys = key.split(".")
        if len(keys) > 1:
            result[keys[0]] = cls.string_to_dict(key=".".join(keys[1:]), value=value, result=result)
            return result
        else:
            return {key: value}

    @classmethod
    def merge_dicts(cls, from_dict: dict, to_dict: dict) -> dict:
        """
        Слияние словарей без перезаписи
        :param from_dict: source
        :param to_dict: additinal
        :return: from_dict >> to_dict
        """
        soft_merged = False
        if not bool(from_dict):
            return to_dict
        if not bool(to_dict):
            return from_dict
        for key, value in cls.recursive_items(to_dict):  # soft merge
            from_value = from_dict.get(key, None)
            if from_value is not None:
                from_value.update(value)
                soft_merged = True
        if soft_merged:
            return from_dict
        else:
            return {**from_dict, **to_dict}  # hard merge

    @classmethod
    def recursive_items(cls, source: dict) -> set:
        for key, value in source.items():
            # print(key, value)
            if type(value) is dict:
                yield key, value
                yield from cls.recursive_items(value)
            else:
                yield key, value


if __name__ == "__main__":
    service = TestPropertiesService()
    print(service.load())
    print(service.env_file)
